package com.ciaojian.client.util;


import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.text.DecimalFormat;
import java.util.*;
import java.util.regex.Pattern;

/**
 * 字符串常用处理<br>
 * 大部分方法借鉴自apache-commons的StringUtils
 *
 * @author cano
 */
public class StringTool {

    /**
     * 避免不小心在类的内部调用构造器. 保证该类在任何情况下都不会被实例化.
     */
    private StringTool() {
    }

    /**
     * 判断字符串是否空<br>
     * 空的定义为：{@code null}或长度为0
     *
     * @param cs
     * @return
     */
    public static boolean isEmpty(final CharSequence cs) {
        return cs == null || cs.length() == 0;
    }

    /**
     * 判断字符串是否带有英文
     * @param valueKey
     * @return
     */
    public static boolean isMatcherEn(String valueKey){
        Pattern p = Pattern.compile("[a-zA-Z]");
        if(p.matcher(valueKey).find()){
            return true;
        }
        return false;
    }

    /**
     * 判断一个字符串是否不为空<br>
     * 空的定义为：{@code null}或长度为0
     *
     * @param cs
     * @return
     */
    public static boolean isNotEmpty(final CharSequence cs) {
        return !isEmpty(cs);
    }

    /**
     * 判断1个以上字符串是否有存在空<br>
     * 空的定义为：{@code null}或长度为0
     *
     * @param css
     * @return
     */
    public static boolean isAnyEmpty(final CharSequence... css) {
        if (ArrayUtil.isEmpty(css)) {
            return true;
        }
        for (CharSequence cs : css) {
            if (isEmpty(cs)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断1个以上字符串是否有不存在空<br>
     * 空的定义为：{@code null}或长度为0
     *
     * @param css
     * @return
     */
    public static boolean isNoneEmpty(final CharSequence... css) {
        return !isAnyEmpty(css);
    }

    /**
     * 判断字符串是否是空白<br>
     * 空白的定义为：{@code null}或长度为0、一个或多个空格
     *
     * @param cs
     * @return
     */
    public static boolean isBlank(final CharSequence cs) {
        int strLen;
        if (cs == null || (strLen = cs.length()) == 0) {
            return true;
        }
        for (int i = 0; i < strLen; i++) {
            if (Character.isWhitespace(cs.charAt(i)) == false) {
                return false;
            }
        }
        return true;
    }


    public static String getText(String htmlStr) {
        if (htmlStr == null || htmlStr.equals("")) {
            return "";
        }
        htmlStr = htmlStr.replaceAll("\\n", "").replaceAll("\\r", "");
        String str = htmlStr.replaceAll("(?s)<!--(.*)-->", "").replaceAll("<.*?>", "").replaceAll("\\&[a-zA-Z]{1,10};", "");
        return str;
    }

    /**
     * 判断是否整数
     */
    public static boolean chkInt(String str) {
        if (str == null || str.trim().equals("")) {
            return false;
        }
        String num = "0123456789";
        for (int i = 0; i < str.length(); i++) {
            if (!num.contains(str.substring(i, i + 1))) {
                return false;
            }
        }
        return true;
    }

    /**
     * 判断是否为数字
     *
     * @param str
     * @return
     */
    public static boolean chkNum(String str) {
        if (str == null || str.trim().equals("")) {
            return false;
        }
        String num = "0123456789.-";
        for (int i = 0; i < str.length(); i++) {
            if (!num.contains(str.substring(i, i + 1))) {
                return false;
            }
        }
        return true;
    }

    /**
     * 将1001,1002,1003形式的参数转化为"('1001','1002','1003')"的形式
     *
     * @param sqlIds
     * @return
     */
    public static String getIdsOfSql(String sqlIds) {
        if (isEmpty(sqlIds)) {
            return "";
        }
        sqlIds = sqlIds.replaceAll("，", ",");
        sqlIds = sqlIds.replaceAll(",", ",");
        String[] ids = sqlIds.split(",");
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < ids.length; i++) {
            if (!isEmpty(ids[i])) {
                sb.append(",'" + ids[i] + "'");
            }
        }
        String result = sb.toString();
        if (result.length() > 0) {
            result = result.substring(1);
        }
        return result;
    }


    /**
     * 判断字符串是否不是空白<br>
     * 空白的定义为：{@code null}或长度为0、一个或多个空格
     *
     * @param cs
     * @return
     */
    public static boolean isNotBlank(final CharSequence cs) {
        return !isBlank(cs);
    }

    /**
     * 判断1个以上字符串是否有空白<br>
     * 空白的定义为：{@code null}或长度为0、一个或多个空格
     *
     * @param css
     * @return
     */
    public static boolean isAnyBlank(final CharSequence... css) {
        if (ArrayUtil.isEmpty(css)) {
            return true;
        }
        for (CharSequence cs : css) {
            if (isBlank(cs)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断1个以上字符串是否不存在空白<br>
     * 空白的定义为：{@code null}或长度为0、一个或多个空格
     *
     * @param css
     * @return
     */
    public static boolean isNoneBlank(final CharSequence... css) {
        return !isAnyBlank(css);
    }

    /**
     * 比较两个字符串是否相等
     *
     * @param cs1        要比较的字符串1
     * @param cs2        要比较的字符串2
     * @param ignoreCase 是否忽略大小写
     * @return 如果两个字符串相同，或者都是<code>null</code>，则返回<code>true</code>
     */
    public static boolean equals(final CharSequence cs1, final CharSequence cs2, boolean ignoreCase) {
        if (cs1 == null) {
            return cs2 == null;
        }

        if (ignoreCase) {
            return cs1.toString().equalsIgnoreCase(cs2.toString());
        } else {
            return cs1.equals(cs2);
        }
    }

    /**
     * 判断两个字符串是否相等（大小写敏感）
     *
     * @param cs1
     * @param cs2
     * @return
     */
    public static boolean isEquals(final CharSequence cs1, final CharSequence cs2) {
        return equals(cs1, cs2, true);
    }

    /**
     * 判断两个字符串是否不相等（大小写敏感）
     *
     * @param cs1
     * @param cs2
     * @return
     */
    public static boolean isNotEquals(final CharSequence cs1, final CharSequence cs2) {
        return !isEquals(cs1, cs2);
    }

    /**
     * 字符串是否以给定字符开始
     *
     * @param str 字符串
     * @param c   字符
     * @return
     */
    public static boolean startWith(CharSequence str, char c) {
        return c == str.charAt(0);
    }

    /**
     * 字符串是否以给定字符结尾
     *
     * @param str 字符串
     * @param c   字符
     * @return
     */
    public static boolean endWith(CharSequence str, char c) {
        return c == str.charAt(str.length() - 1);
    }

    /**
     * 获得字符串长度<br>
     * 为{@code null}时返回0
     *
     * @param cs
     * @return
     */
    public static int length(final CharSequence cs) {
        return cs == null ? 0 : cs.length();
    }

    /**
     * 删掉字符串中所有的空白符
     *
     * @param str
     * @return
     */
    public static String trim(final String str) {
        return str == null ? null : str.trim();
    }

    /**
     * 删掉字符串中所有的空白符，包括全角空格
     *
     * @param str
     * @return
     */
    public static String trimIncludeSBC(final String str) {
        return str == null ? null : str.trim().replaceAll("　", Consts.EMPTY);
    }

    /**
     * 删除字符串左边的空白符
     *
     * @param str
     * @return
     */
    public static String trimLeft(final String str) {
        if (isEmpty(str)) {
            return Consts.EMPTY;
        }

        StringBuilder sb = new StringBuilder(str);
        while (sb.length() > 0 && Character.isWhitespace(sb.charAt(0))) {
            sb.deleteCharAt(0);
        }
        return sb.toString();
    }

    /**
     * 删除字符串右边的空白符
     *
     * @param str
     * @return
     */
    public static String trimRight(final String str) {
        if (isEmpty(str)) {
            return Consts.EMPTY;
        }

        StringBuilder sb = new StringBuilder(str);
        while (sb.length() > 0 && Character.isWhitespace(sb.charAt(sb.length() - 1))) {
            sb.deleteCharAt(sb.length() - 1);
        }
        return sb.toString();
    }

    /**
     * 字符串拼接
     *
     * @param separator 分隔符，为{@code null}时表示不加分隔符
     * @param skipNull  是否跳过{@code null}，false时字符串为{@code null}直接转成空字符串""
     * @param args      待拼接的字符串数组
     * @return
     */
    public static String join(String separator, final boolean skipNull, final Object... args) {
        if (separator == null) {
            separator = Consts.EMPTY;
        }
        StringBuilder buf = new StringBuilder();
        for (Object arg : args) {
            if (arg != null) {
                if (buf.length() > 0) {
                    buf.append(separator);
                }
                buf.append(arg.toString());
            } else if (!skipNull) {
                if (buf.length() > 0) {
                    buf.append(separator);
                }
                buf.append(Consts.NULL);
            }
        }
        return buf.toString();
    }

    /**
     * 字符串拼接<br>
     * 字符串为{@code null}直接转成""
     *
     * @param array     待拼接的字符串数组
     * @param separator 分隔符，为{@code null}时表示不加分隔符
     * @return
     */
    public static String join(final Object[] array, String separator) {
        return join(separator, true, array);
    }

    /**
     * 字符串拼接
     *
     * @param args
     * @return
     */
    public static String concat(final Object... args) {
        return join(args, null);
    }

    /**
     * 字符串分隔
     *
     * @param str
     * @param separatorChar     分隔字符
     * @param preserveAllTokens 多个分隔符在一起时是否当成一个分隔符
     * @return
     */
    public static String[] split(final String str, final char separatorChar, final boolean preserveAllTokens) {
        if (str == null) {
            return null;
        }
        final int len = str.length();
        if (len == 0) {
            return ArrayUtil.EMPTY_STRING_ARRAY;
        }
        final List<String> list = new ArrayList<String>();
        int i = 0, start = 0;
        boolean match = false;
        boolean lastMatch = false;
        while (i < len) {
            if (str.charAt(i) == separatorChar) {
                if (match || preserveAllTokens) {
                    list.add(str.substring(start, i));
                    match = false;
                    lastMatch = true;
                }
                start = ++i;
                continue;
            }
            lastMatch = false;
            match = true;
            i++;
        }
        if (match || preserveAllTokens && lastMatch) {
            list.add(str.substring(start, i));
        }
        return list.toArray(new String[list.size()]);
    }

    /**
     * 字符串分隔<br>
     * 多个分隔符在一起时会当成一个分隔符
     *
     * @param str
     * @param separatorChar
     * @return
     */
    public static String[] split(final String str, final char separatorChar) {
        return split(str, separatorChar, true);
    }

    /**
     * 字符串分隔
     *
     * @param str
     * @param separator         分隔符，为{@code null}时表示以一个空格为分隔
     * @param max               数组中包含的元素的最大数目,零值或负值表示没有限制
     * @param preserveAllTokens 多个分隔符在一起时是否当成一个分隔符
     * @return
     */
    public static String[] split(final String str, final String separator, final int max, final boolean
            preserveAllTokens) {
        if (str == null) {
            return null;
        }
        final int len = str.length();
        if (len == 0) {
            return ArrayUtil.EMPTY_STRING_ARRAY;
        }
        if (separator == null) {
            return split(str, Consts.EMPTY_CHAR, preserveAllTokens);
        } else if (separator.length() == 1) {
            return split(str, separator.charAt(0), preserveAllTokens);
        } else {
            final List<String> list = new ArrayList<String>();
            int sizePlus1 = 1;
            int i = 0, start = 0;
            boolean match = false;
            boolean lastMatch = false;
            while (i < len) {
                if (separator.indexOf(str.charAt(i)) >= 0) {
                    if (match || preserveAllTokens) {
                        lastMatch = true;
                        if (sizePlus1++ == max) {
                            i = len;
                            lastMatch = false;
                        }
                        list.add(str.substring(start, i));
                        match = false;
                    }
                    start = ++i;
                    continue;
                }
                lastMatch = false;
                match = true;
                i++;
            }
            if (match || preserveAllTokens && lastMatch) {
                list.add(str.substring(start, i));
            }
            return list.toArray(new String[list.size()]);
        }
    }

    /**
     * 字符串分隔<br>
     * 多个分隔符在一起时会当成一个分隔符
     *
     * @param str
     * @param separator
     * @return
     */
    public static String[] split(final String str, final String separator) {
        return split(str, separator, -1, true);
    }

    /**
     * 字符串按字节长度截取
     *
     * @param str    待截取的字符串
     * @param len    需要显示的长度<br>
     *               (<font color="red">注意：长度是以byte为单位的，一个汉字是2个byte</font>)
     * @param symbol 用于表示省略的信息的字符，如“...”,“>>>”等。
     * @return
     */
    public static String sub(final String str, final int len, final String symbol) {
        if (isEmpty(str)) {
            return Consts.EMPTY;
        }
        try {
            int counterOfDoubleByte = 0;
            byte[] b = str.getBytes(Charsets.GBK);
            if (b.length <= len) {
                return str;
            }

            for (int i = 0; i < len; i++) {
                // 通过判断字符的类型来进行截取
                if (b[i] < 0) {
                    counterOfDoubleByte++;
                }
            }
            if (counterOfDoubleByte % 2 == 0) {
                return concat(new String(b, 0, len, Charsets.GBK), symbol == null ? Consts.EMPTY : symbol);
            } else {
                return concat(new String(b, 0, len - 1, Charsets.GBK), symbol == null ? Consts.EMPTY : symbol);
            }
        } catch (UnsupportedEncodingException e) {
            return str;
        }
    }

    /**
     * 字符串按字节长度截取
     *
     * @param str 待截取的字符串
     * @param len 需要显示的长度<br>
     *            (<font color="red">注意：长度是以byte为单位的，一个汉字是2个byte</font>)
     * @return
     */
    public static String sub(final String str, final int len) {
        return sub(str, len, null);
    }

    /**
     * 改进JDK subString<br>
     * index从0开始计算，最后一个字符为-1
     *
     * @param str
     * @param fromIndex
     * @param toIndex
     * @return
     */
    public static String subString(final String str, int fromIndex, int toIndex) {
        if (isEmpty(str)) {
            return Consts.EMPTY;
        }
        int len = str.length();
        if (fromIndex < 0) {
            fromIndex = len + fromIndex;
            if (toIndex == 0) {
                toIndex = len;
            }
        }
        if (toIndex < 0) {
            toIndex = len + toIndex + 1;
        }
        if (toIndex < fromIndex) {
            int tmp = fromIndex;
            fromIndex = toIndex;
            toIndex = tmp;
        }
        if (fromIndex == toIndex) {
            return Consts.EMPTY;
        }
        char[] strArray = str.toCharArray();
        char[] newStrArray = Arrays.copyOfRange(strArray, fromIndex, toIndex);
        return new String(newStrArray);
    }

    /**
     * 改进JDK subString
     *
     * @param str
     * @param fromIndex
     * @return
     */
    public static String subString(final String str, int fromIndex) {
        return subString(str, fromIndex, -1);
    }

    /**
     * 补充字符串以满足最小长度<br>
     * StringUtil.leftPad("1", 3, '0');//"001"
     *
     * @param str       字符串
     * @param minLength 最小长度
     * @param padChar   补充的字符
     * @return 补充后的字符串
     */
    public static String leftPad(final String str, final int minLength, final char padChar) {
        if (str == null || str.length() >= minLength) {
            return str;
        }
        StringBuilder sb = new StringBuilder(minLength);
        for (int i = str.length(); i < minLength; i++) {
            sb.append(padChar);
        }
        sb.append(str);
        return sb.toString();
    }

    /**
     * 补充字符串以满足最小长度<br>
     * StringUtil.rightPad("1", 3, '0');//"100"
     *
     * @param str       字符串
     * @param minLength 最小长度
     * @param padChar   补充的字符
     * @return 补充后的字符串
     */
    public static String rightPad(final String str, final int minLength, final char padChar) {
        if (str == null || str.length() >= minLength) {
            return str;
        }
        StringBuilder sb = new StringBuilder(minLength);
        sb.append(str);
        for (int i = str.length(); i < minLength; i++) {
            sb.append(padChar);
        }
        return sb.toString();
    }

    /**
     * 去掉指定前缀
     *
     * @param str        字符串
     * @param prefix     前缀
     * @param ignoreCase 是否区分大小写
     * @return 切掉后的字符串，若前缀不是 prefix， 返回原字符串
     */
    public static String removePrefix(final String str, final String prefix, final boolean ignoreCase) {
        if (isEmpty(str) || isEmpty(prefix)) {
            return str;
        }
        if (ignoreCase) {
            if (str.startsWith(prefix)) {
                // 截取后半段
                return subString(str, prefix.length(), str.length());
            }
        } else {
            if (str.toLowerCase().startsWith(prefix.toLowerCase())) {
                // 截取后半段
                return subString(str, prefix.length(), str.length());
            }
        }
        return str;
    }

    /**
     * 去掉指定后缀
     *
     * @param str        字符串
     * @param suffix     后缀
     * @param ignoreCase 是否区分大小写
     * @return 切掉后的字符串，若后缀不是 suffix， 返回原字符串
     */
    public static String removeSuffix(final String str, final String suffix, final boolean ignoreCase) {
        if (isEmpty(str) || isEmpty(suffix)) {
            return str.toString();
        }
        if (ignoreCase) {
            if (str.endsWith(suffix)) {
                return subString(str, 0, str.length() - suffix.length());
            }
        } else {
            if (str.toLowerCase().endsWith(suffix.toLowerCase())) {
                return subString(str, 0, str.length() - suffix.length());
            }
        }
        return str;
    }

    /**
     * 将给定字符串，变成 "xxx...xxx" 形式的字符串
     *
     * @param str
     * @param len
     * @return
     */
    public static String brief(final String str, final int len) {
        if (isBlank(str) || (str.length() + 3) <= len) {
            return str;
        }
        int w = len / 2;
        int l = str.length();
        return subString(str, 0, len - w) + " ... " + subString(str, l - w);
    }

    /**
     * 判断字符串中是否含有某串字符串中的一个<br>
     * 只要包含其中一个返回{@code true}
     *
     * @param str
     * @param searchStr
     * @return
     */
    public static boolean contains(final String str, final String[] searchStr) {
        if (isEmpty(str) || searchStr == null || searchStr.length == 0) {
            return false;
        }
        for (String ss : searchStr) {
            if (str.indexOf(ss) != -1) {
                return true;
            }
        }
        return false;
    }

    /**
     * 使HTML的标签失去作用
     *
     * @param html 被操作的字符串
     * @return
     */
    public static final String escapeHTMLTag(String html) {
        if (html == null) {
            return "";
        }
        html = html.trim().replaceAll("&", "&amp;");
        html = html.replaceAll("<", "&lt;");
        html = html.replaceAll(">", "&gt;");
        html = html.replaceAll("\n", "<br>");
        html = html.replaceAll("'", "&#39;");
        html = html.replaceAll("\"", "&quot;");
        html = html.replaceAll("\\\\", "&#92;");
        return html;
    }

    /**
     * 去掉html代码
     *
     * @param html
     * @return
     */
    public static String trimHtml(String html) {
        if (isEmpty(html)) {
            return Consts.EMPTY;
        }
        return html.replaceAll("<.*?>", Consts.EMPTY);
    }

    /**
     * 去掉空格、换行、制表符
     *
     * @param input
     * @return
     */
    public static String trimSpace(String input) {
        if (isEmpty(input)) {
            return Consts.EMPTY;
        }
        return input.replaceAll("\\s*|\t|\r|\n", Consts.EMPTY);
    }

    /**
     * 百分比转换
     *
     * @param str
     * @return
     */
    public static String percent(final String str) {
        return new DecimalFormat("##%").format(Conver.toDouble(str, 0d));
    }

    /**
     * 将字符串中指定位置({@code index})的字符(必须在{@linkplain Character#toLowerCase(char)})转为大(小)写,否则就不会改变<br>
     * StringUtil.changeCase("Hello",2,true); //--- "HeLlo"
     *
     * @param str     字符串
     * @param index   大小写更改位置
     * @param capital 大写还是小写，当值为{@code true}时则大写，值为{@code false}时则小写
     * @return 返回修改后的字符串
     */
    public static String changeCase(final String str, int index, final boolean capital) {
        if (isEmpty(str)) {
            return Consts.EMPTY;
        }

        int pos;
        if (index < 0) {
            pos = str.length() + index;
        } else {
            pos = index;
        }
        StringBuilder sb = new StringBuilder(str.length());
        sb.append(str.subSequence(0, pos));
        if (capital) {
            sb.append(Character.toUpperCase(str.charAt(pos)));
        } else {
            sb.append(Character.toLowerCase(str.charAt(pos)));
        }
        sb.append(str.substring(pos + 1));
        return sb.toString();
    }

    /**
     * 将驼峰式命名的字符串转换为下划线字符串<br>
     * 如果转换前的驼峰式命名的字符串为空，则返回空字符串
     *
     * @param name
     * @param upper
     * @return
     */
    public static String toUnderline(final String name, final boolean upper) {
        if (isEmpty(name)) {
            return Consts.EMPTY;
        }

        StringBuilder builder = new StringBuilder(name.length());
        char[] chars = name.toCharArray();
        char ch;
        for (int i = 0, length = chars.length; i < length; i++) {
            ch = chars[i];
            if (Character.isUpperCase(ch)) {
                if (i != 0) {
                    builder.append("_");
                }
                builder.append(upper ? ch : Character.toLowerCase(ch));
            } else {
                builder.append(upper ? Character.toUpperCase(ch) : ch);
            }
        }
        return builder.toString();
    }

    /**
     * 将下划线大写方式命名的字符串转换为驼峰式<br>
     * 如果转换前的下划线大写方式命名的字符串为空，则返回空字符串<br>
     * 如：HELLO_WORLD - helloWorld
     *
     * @param name
     * @return
     */
    public static String toCamelCase(final String name) {
        if (isEmpty(name)) {
            return Consts.EMPTY;
        }

        boolean headerFirstUnderline = false;
        StringBuilder builder = new StringBuilder(name.length());
        char[] chars = name.toCharArray();
        char ch;

        for (int i = 0, length = chars.length; i < length; i++) {
            ch = chars[i];

            if (ch == '_') {
                if (chars[i + 1] == '_') {
                    if (i == 0) {
                        headerFirstUnderline = true;
                    }
                    continue;
                } else if (i == 0) {
                    headerFirstUnderline = true;
                }
                i++;
                ch = chars[i];
                if (headerFirstUnderline) {
                    builder.append(Character.toLowerCase(ch));
                    headerFirstUnderline = false;
                } else {
                    builder.append(Character.toUpperCase(ch));
                }
            } else {
                builder.append(Character.toLowerCase(ch));
            }
        }
        return builder.toString();
    }

    /**
     * key方式格式化文本
     *
     * @param template 文本模板，被替换的部分用 {key} 表示
     * @param map      参数值对
     * @return 格式化后的文本
     */
    public static String format(String template, final Map<?, ?> map) {
        if (null == map || map.isEmpty()) {
            return template;
        }
        for (Map.Entry<?, ?> entry : map.entrySet()) {
            template = template.replace("{" + entry.getKey() + "}", entry.getValue().toString());
        }
        return template;
    }

    /**
     * 格式化字符串<br>
     * 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
     * 如果想输出 {} 使用 \\转义 { 即可，如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
     * 例：<br>
     * 通常使用：format("this is {} for {}", "a", "b") =》 this is a for b<br>
     * 转义{}： format("this is \\{} for {}", "a", "b") =》 this is \{} for a<br>
     * 转义\：	format("this is \\\\{} for {}", "a", "b") =》 this is \a for b<br>
     *
     * @param strPattern 字符串模板
     * @param argArray   参数列表
     * @return
     */
    public static String format(final String strPattern, final Object... argArray) {
        if (StringTool.isBlank(strPattern) || ArrayUtil.isEmpty(argArray)) {
            return strPattern;
        }
        final int strPatternLength = strPattern.length();

        //初始化定义好的长度以获得更好的性能
        StringBuilder sbuf = new StringBuilder(strPatternLength + 50);
        //记录已经处理到的位置
        int handledPosition = 0;
        //占位符所在位置
        int delimIndex;
        for (int argIndex = 0; argIndex < argArray.length; argIndex++) {
            delimIndex = strPattern.indexOf(Consts.EMPTY_JSON, handledPosition);
            //剩余部分无占位符
            if (delimIndex == -1) {
                //不带占位符的模板直接返回
                if (handledPosition == 0) {
                    return strPattern;
                } else {
                    //字符串模板剩余部分不再包含占位符，加入剩余部分后返回结果
                    sbuf.append(strPattern, handledPosition, strPatternLength);
                    return sbuf.toString();
                }
            } else {
                //转义符
                if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == Consts.BACK_SLASH) {
                    //双转义符
                    if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == Consts.BACK_SLASH) {
                        //转义符之前还有一个转义符，占位符依旧有效
                        sbuf.append(strPattern, handledPosition, delimIndex - 1);
                        sbuf.append(argArray[argIndex]);
                        handledPosition = delimIndex + 2;
                    } else {
                        //占位符被转义
                        argIndex--;
                        sbuf.append(strPattern, handledPosition, delimIndex - 1);
                        sbuf.append("{");
                        handledPosition = delimIndex + 1;
                    }
                } else {//正常占位符
                    sbuf.append(strPattern, handledPosition, delimIndex);
                    sbuf.append(argArray[argIndex]);
                    handledPosition = delimIndex + 2;
                }
            }
        }
        //加入最后一个占位符后所有的字符
        sbuf.append(strPattern, handledPosition, strPattern.length());
        return sbuf.toString();
    }

    /**
     * urlencode
     *
     * @param str
     * @param coding
     * @return
     */
    public static String encode(final String str, final String coding) {
        if (isEmpty(str)) {
            return Consts.EMPTY;
        }
        try {
            return java.net.URLEncoder.encode(str, coding);
        } catch (Exception e) {
            return str;
        }
    }

    /**
     * utf8 urlencode
     *
     * @param str
     * @return
     */
    public static String encode(final String str) {
        return encode(str, Charsets.UTF_8);
    }

    /**
     * urldecode
     *
     * @param str
     * @param coding
     * @return
     */
    public static String decode(final String str, final String coding) {
        if (isEmpty(str)) {
            return Consts.EMPTY;
        }
        try {
            return java.net.URLDecoder.decode(str, coding);
        } catch (Exception e) {
            return str;
        }
    }

    /**
     * utf8 urldecode
     *
     * @param str
     * @return
     */
    public static String decode(final String str) {
        return decode(str, Charsets.UTF_8);
    }

    /**
     * 获取带横线的长度为36的UUID串
     *
     * @return
     */
    public static String get36UUID() {
        return UUID.randomUUID().toString();
    }

    /**
     * 获取去掉横线的长度为32的UUID串
     *
     * @return
     */
    public static String get32UUID() {
        return get36UUID().replace("-", "");
    }

    /**
     * 获得StringReader
     *
     * @param str 字符串
     * @return StringReader
     */
    public static StringReader getReader(CharSequence str) {
        if (null == str) {
            return null;
        }
        return new StringReader(str.toString());
    }

    public static String getCanUseStr(String sourceStr, String replaceStr) {
        if (isEmpty(sourceStr)) {
            sourceStr = replaceStr;
        }
        if (replaceStr != null && sourceStr.toLowerCase().trim().equals("null")) {
            sourceStr = replaceStr;
        }
        return sourceStr;
    }

    /**
     * 判断是否由数字组成的字符串
     *
     * @param s
     * @return
     */
    public static boolean isNumSeq(String s) {
        boolean isNum = true;
        String nums = "0123456789";
        String temp_str;
        for (int i = 0; i < s.length(); i++) {
            temp_str = s.substring(i, i + 1);
            if (nums.indexOf(temp_str) == -1) {
                isNum = false;
                break;
            }
        }
        return isNum;
    }


}
